﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using System.Data;

namespace Constructor
{
    public partial class AdvDGV : DataGridView
    {
        public AdvDGV()
        {
            InitializeComponent();
            Construct();
        }

        public AdvDGV(IContainer container)
        {
            container.Add(this);

            InitializeComponent();
            Construct();
        }

        public bool SelectCOLORRow
        {
            get;
            set;
        }

        Timer UpDownMove;
        private void Construct()
        {
            UpDownMove = new Timer();
            UpDownMove.Interval = 200;
            UpDownMove.Tick += new EventHandler(UpMove_Tick);
            _Moving = false;

        }

        void UpMove_Tick(object sender, EventArgs e)
        {
            AdvDGV_MouseMove(this, new MouseEventArgs(System.Windows.Forms.MouseButtons.Left, 0, last_loc.X, last_loc.Y, 0));
        }

        DataGridViewRow last_cr = null;
        protected override void OnCurrentCellChanged(EventArgs e)
        {
            if (SelectCOLORRow)
            {
                if (last_cr != null)
                {
                    foreach (DataGridViewCell dc in last_cr.Cells)
                        dc.Style.BackColor = Color.White;
                }
                if (CurrentRow != null)
                {
                    last_cr = CurrentRow;
                    foreach (DataGridViewCell dc in CurrentRow.Cells)
                    {
                        dc.Style.BackColor = Color.LightGreen;
                    }
                }
            }
            base.OnCurrentCellChanged(e);
        }

        protected override void OnRowsAdded(DataGridViewRowsAddedEventArgs e)
        {
            base.OnRowsAdded(e);
            foreach (DataGridViewRow dr in Rows)
                if (dr != null)
                {
                    foreach (DataGridViewCell dc in dr.Cells)
                        dc.Style.BackColor = Color.White;
                }
        }

        protected override void OnMouseClick(MouseEventArgs e)
        {
            try
            {
                base.OnMouseClick(e);
                base.OnMouseClick(e);
            }
            catch { }
        }

        #region MoveItems
        private bool _Moving;
        private int _MvngRow;
        DataGridViewSelectionMode LastMode;
        bool LastMultiSelect;

        private void AdvDGV_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                LastMode = this.SelectionMode;
                this.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
                LastMultiSelect = this.MultiSelect;
                this.MultiSelect = false;
                _MvngRow = GetRowFromLocation(e.Location);
                if (_MvngRow != -1 && GetColumnFromLocation(e.Location) == -2)
                    _Moving = true;
            }
        }

        private void AdvDGV_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                _Moving = false;
                this.SelectionMode = LastMode;
                this.MultiSelect = LastMultiSelect;
            }
        }

        Point eMouseLocation()
        {
            Point result = this.PointToScreen(new Point(0, 0));
            result = new Point(MousePosition.X - result.X, MousePosition.Y - result.Y);
            return result;
        }

        Point last_loc = Point.Empty;
        private void AdvDGV_MouseMove(object sender, MouseEventArgs e)
        {
            if (_Moving && e.Button == MouseButtons.Left)
            {
                last_loc = e.Location;
                last_loc = eMouseLocation();
                int CurRow = GetRowFromLocation(e.Location);
                if (!(CurRow < 0))
                {
                    if (UpDownMove.Enabled)
                    {
                        UpDownMove.Stop();
                        this.MouseMove += new MouseEventHandler(AdvDGV_MouseMove);
                    }
                }
                else
                {
                    if (!UpDownMove.Enabled)
                    {
                        UpDownMove.Start();
                        this.MouseMove -= AdvDGV_MouseMove;
                        return;
                    }
                    if (CurRow == -1)
                    {
                        CurRow = FirstDisplayedScrollingRowIndex + this.DisplayedRowCount(false);
                        if (!(CurRow < Rows.Count))
                            CurRow = -1;
                    }
                    if (CurRow == -2)
                        CurRow = FirstDisplayedScrollingRowIndex - 1;
                }
                if (CurRow >= 0 && CurRow != _MvngRow && !(CurRow == Rows.Count - 1 && AllowUserToAddRows))
                {
                    object[] prmtrs1 = new object[Columns.Count];
                    object[] prmtrs2 = new object[Columns.Count];
                    for (int i = 0; i < Columns.Count; i++)
                    {
                        prmtrs1[i] = Rows[_MvngRow].Cells[i].Value;
                        prmtrs2[i] = Rows[CurRow].Cells[i].Value;
                    }
                    if (this.DataSource == null)
                    {
                        for (int i = 0; i < Columns.Count; i++)
                        {
                            object temp = Rows[CurRow].Cells[i].Value;
                            Rows[CurRow].Cells[i].Value = "-12345678";
                            Rows[_MvngRow].Cells[i].Value = temp;
                            Rows[CurRow].Cells[i].Value = prmtrs1[i];
                        }
                    }
                    else
                    {
                        string RealMember = DataMember;
                        switch (DataMember)
                        {
                            case "domens.domens_and_dparams":
                                RealMember = "domens_params";
                                break;
                            case "rules.rules_and_expressions":
                                {
                                    RealMember = "expressions";
                                    int mvrow = ((DataViewManager)DataSource).DataSet.Tables[RealMember].Rows.IndexOf(
                                        ((((DataViewManager)DataSource).DataSet.Tables[RealMember]).Select("Название_правила='" + prmtrs2[0].ToString() + "'"))[_MvngRow]);
                                    int crrow = ((DataViewManager)DataSource).DataSet.Tables[RealMember].Rows.IndexOf(
                                        ((((DataViewManager)DataSource).DataSet.Tables[RealMember]).Select("Название_правила='" + prmtrs2[0].ToString() + "'"))[CurRow]);
                                    ((DataViewManager)DataSource).DataSet.Tables[RealMember].BeginLoadData();
                                    ((DataViewManager)DataSource).DataSet.Tables[RealMember].Rows[mvrow].ItemArray = prmtrs2;
                                    ((DataViewManager)DataSource).DataSet.Tables[RealMember].Rows[crrow].ItemArray = prmtrs1;
                                    ((DataViewManager)DataSource).DataSet.Tables[RealMember].EndLoadData();
                                    break;
                                }
                            case "rules.rules_and_conclusions":
                                {
                                    RealMember = "conclusions";
                                    int mvrow = ((DataViewManager)DataSource).DataSet.Tables[RealMember].Rows.IndexOf(
                                        ((((DataViewManager)DataSource).DataSet.Tables[RealMember]).Select("Название_правила='" + prmtrs2[0].ToString() + "'"))[_MvngRow]);
                                    int crrow = ((DataViewManager)DataSource).DataSet.Tables[RealMember].Rows.IndexOf(
                                        ((((DataViewManager)DataSource).DataSet.Tables[RealMember]).Select("Название_правила='" + prmtrs2[0].ToString() + "'"))[CurRow]);
                                    ((DataViewManager)DataSource).DataSet.Tables[RealMember].BeginLoadData();
                                    ((DataViewManager)DataSource).DataSet.Tables[RealMember].Rows[mvrow].ItemArray = prmtrs2;
                                    ((DataViewManager)DataSource).DataSet.Tables[RealMember].Rows[crrow].ItemArray = prmtrs1;
                                    ((DataViewManager)DataSource).DataSet.Tables[RealMember].EndLoadData();
                                    break;
                                }
                            default:
                                {
                                    ((DataViewManager)DataSource).DataSet.Tables[RealMember].BeginLoadData();
                                    ((DataViewManager)DataSource).DataSet.Tables[RealMember].Rows[_MvngRow].ItemArray = prmtrs2;
                                    ((DataViewManager)DataSource).DataSet.Tables[RealMember].Rows[CurRow].ItemArray = prmtrs1;
                                    ((DataViewManager)DataSource).DataSet.Tables[RealMember].EndLoadData();
                                    break;
                                }
                        }

                        OnRowExchange(EventArgs.Empty);
                    }

                    _MvngRow = CurRow;
                    this.Rows[_MvngRow].Selected = true;
                    this.CurrentCell = Rows[_MvngRow].Cells[FirstDisplayedScrollingColumnIndex];
                }
            }
        }

        public event EventHandler RowExchange;

        protected virtual void OnRowExchange(EventArgs e)
        {
            if (RowExchange != null)
                RowExchange(this, e);
        }

        private int GetRowFromLocation(Point pt)
        {
            int i = 0;
            foreach (DataGridViewRow drw in Rows)
            {
                if (GetRowDisplayRectangle(i, false).Contains(pt))
                    return i;
                i++;
            }
            if (pt.Y < this.Height - 5)
                return -2;
            else
                return -1;
        }

        private int GetColumnFromLocation(Point pt)
        {
            int i = 0;
            foreach (DataGridViewColumn drw in Columns)
            {
                if (GetColumnDisplayRectangle(i, false).Contains(pt))
                    return i;
                i++;
            }
            if (GetColumnDisplayRectangle(FirstDisplayedScrollingColumnIndex, false).Left > pt.X)
                return -2;
            return -1;
        }
        #endregion
    }
}
